home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / metamail / contrib / mms / mmssynthe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-04  |  8.1 KB  |  380 lines

  1. /*////////////////////////////////////////////////////////////////////////
  2. Copyright (c) 1992 Electrotechnical Laboratry (ETL)
  3.  
  4. Permission to use, copy, modify, and distribute this material 
  5. for any purpose and without fee is hereby granted, provided 
  6. that the above copyright notice and this permission notice 
  7. appear in all copies, and that the name of ETL not be 
  8. used in advertising or publicity pertaining to this 
  9. material without the specific, prior written permission 
  10. of an authorized representative of ETL.
  11. ETL MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY 
  12. OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", 
  13. WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  14. /////////////////////////////////////////////////////////////////////////
  15. Content-Type: program/C; charset=US-ASCII
  16. Program:      mmssynth.c  (MIME message synthesizer)
  17. Author:       Yutaka Sato <ysato@etl.go.jp>
  18.  
  19. History:
  20.   v0.1  92.05.03  extracted from mms.c (mailto dependent version)
  21.     930505    fixed the inconsistency of MailcapEntry with mailto.o
  22.     930505    suppress the automatic header encoding in HeaderFputs
  23. ///////////////////////////////////////////////////////////////////////*/
  24.  
  25. #include <stdio.h>
  26. char *getenv();
  27. char *MMS_freshcopy();
  28.  
  29.  
  30. /*////////////////////////////////////////////////////////////////////////
  31.  *    mailpart (copyied from mailto.o)
  32.  */
  33. struct mailpart {
  34.     int istext;
  35.     int isrich;
  36.     char *content_type;
  37.     int encoding_type_needed;
  38.     char *filename;
  39.     struct MailcapEntry *mc;
  40.     struct mailpart *next, *prev;
  41. };
  42. /*
  43.  *    mailcap (copied from mailto.o)
  44.  */
  45. struct MailcapEntry {
  46.     char *contenttype;
  47.     char *command;
  48.     char *testcommand;
  49.     char *editcommand;
  50.     char *composecommand;
  51.     char *composetypedcommand;
  52.     char *label;
  53.     int needsterminal;
  54.     int copiousoutput;
  55.     struct MailcapEntry *next;
  56. };
  57. /*//////////////////////////////////////////////////////////////////////*/
  58.  
  59.  
  60. char *MailcapPath =
  61. "%s/.mailcap:%s/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap";
  62.  
  63. #define ENC_NONE    0
  64. static struct mailpart *CurrentPart;
  65. extern struct MailcapEntry *FirstMailcapEntry;
  66.  
  67. extern FILE *fpout;
  68. extern char *CharacterSet;
  69. extern struct mailpart *FirstPart,*NewPart();
  70.  
  71. static char *Subject = NULL;
  72. static char *ToList = NULL;
  73. static char *CCList= NULL;
  74. static char *NGList= NULL;
  75. static int EightBitMode = 0;
  76. static int RightToLeftMode = 0;
  77.  
  78. struct {
  79.     char    *a_name;
  80.     char     a_on[50];
  81.     char     a_off[50];
  82. } char_attrs[] = {
  83.     0,
  84.     {"underline"},
  85.     {"italic"},
  86.     {"bold"},
  87.     {"excerpt"},
  88.     0
  89. };
  90. static known_chattr(chattr)
  91.     char *chattr;
  92. {    int ai;
  93.     char *name;
  94.  
  95.     for(ai = 1; name = char_attrs[ai].a_name; ai++)
  96.         if( strcmp(chattr,name) == 0 )
  97.             return ai;
  98.     return 0;
  99. }
  100.  
  101. MMS_mailtoReSetup(){
  102.     ProcessInitFiles();
  103. }
  104. MMS_mailtoSetup(){
  105.     ProcessInitFiles();
  106.     InitSignals();
  107.     InitTerminal();
  108.  
  109.     CharacterSet = getenv("MM_CHARSET");
  110.     if( !CharacterSet )
  111.         CharacterSet = "us-ascii";
  112.  
  113.     FirstPart = NewPart();
  114.     CurrentPart = FirstPart;
  115.     fpout = fopen((CurrentPart)->filename,"w");
  116.  
  117.     MMS_ProcessMailcap(0);
  118. }
  119.  
  120. MMS_synthAddPart(p,errmsg)
  121.     struct mailpart *p;
  122.     char *errmsg;
  123. {
  124.     TempCloseStyles(fpout);
  125.     fclose(fpout);
  126.     CurrentPart->next = p;
  127.     CurrentPart->next->prev = CurrentPart;
  128.     CurrentPart = CurrentPart->next;
  129.     CurrentPart->next = NewPart();
  130.     CurrentPart->next->prev = CurrentPart;
  131.     CurrentPart = CurrentPart->next;
  132.     fpout = fopen((CurrentPart)->filename,"w");
  133.     if( fpout == NULL )
  134.         return -1;
  135.     ReopenStyles(fpout, CurrentPart);
  136.     return 0;
  137. }
  138.  
  139. MMS_synthSubject(subject)
  140.     char *subject;
  141. {
  142.     Subject = MMS_freshcopy(subject);
  143. }
  144.  
  145. char *AddToList();
  146. MMS_synthAddHead(field,entry,errmsg)
  147.     char *field,*entry,*errmsg;
  148. {
  149.     MMS_touppers(field);
  150.     if( strcmp(field,"TO") == 0 ){
  151.         ToList = AddToList(ToList,entry);
  152.     }else
  153.     if( strcmp(field,"CC") == 0 ){
  154.         CCList = AddToList(CCList,entry);
  155.     }else
  156.     if( strcmp(field,"NEWSGROUPS") == 0 ){
  157.         NGList = AddToList(NGList,entry);
  158.     }else{
  159.         sprintf(errmsg,"unknown header [%s].",field);
  160.         return -1;
  161.     }
  162.     return 0;
  163. }
  164.  
  165. struct mailpart *
  166. MMS_synthEncloseFile(ctype,ifp,errmsg)
  167.     char *ctype;
  168.     FILE *ifp;
  169.     char *errmsg;
  170. {    FILE *ofp;
  171.     struct mailpart *mp;
  172.  
  173.     mp = NewPart();
  174.     ofp = fopen(mp->filename,"w");
  175.     if( ofp == NULL ){
  176.         sprintf(errmsg,"cannot open tempfile: %s",mp->filename);
  177.         fclose(ifp);
  178.         return 0;
  179.     }
  180.     TranslateInputToEncodedOutput(ifp,ofp,ENC_NONE);
  181.     fclose(ofp);
  182.     mp->istext = 0;
  183.     mp->content_type = MMS_freshcopy(ctype);
  184.     mp->encoding_type_needed = WhichEncodingForFile(mp->filename);
  185.     return mp;
  186. }
  187.  
  188. MMS_synthAddText(ifp)
  189.     FILE *ifp;
  190. {    int lines = 0;
  191.     char xline[2048];
  192.  
  193.     while( MMS_getline(xline,sizeof(xline),ifp) != NULL ){
  194.         FputsQuotingLT(xline, fpout, CurrentPart,
  195.             EightBitMode, RightToLeftMode);
  196.         lines++;
  197.     }
  198.     return lines;
  199. }
  200.  
  201. MMS_synthToggleTextAttr(okcode,errcode,okmsg,chattrs)
  202.     char *okmsg,*chattrs;
  203. {    char chattr[256];
  204.     int ai;
  205.  
  206.     if( *chattrs == 0 || sscanf(chattrs,"%s",chattr) == 0 ){
  207.         MMS_status0(okcode,okmsg);
  208.     }else
  209.     if( ai = known_chattr(chattr) ){
  210.         MMS_statusN(okcode,okmsg);
  211.         ToggleStyle(chattr,fpout,CurrentPart,
  212.             char_attrs[ai].a_on, char_attrs[ai].a_off);
  213.         MMS_response_done();
  214.         return okcode;
  215.     }else{
  216.         MMS_status0(errcode,"UNKNOWN character attribute(%s)",chattr);
  217.         return errcode;
  218.     }
  219. }
  220.  
  221. /*////////////////////////////////////////////////////////////////////////
  222.  *    list Content-Type  (using mailto.o)
  223.  */
  224. MMS_ProcessMailcap(force)
  225. {    static int initdone;
  226.     char *home,*lib;
  227.  
  228.     if( force || !initdone ){
  229.         initdone = 1;
  230.         home = getenv("HOME");
  231.         lib = getenv("SYSLIB");
  232.         MMS_putenv("MAILCAPS",MailcapPath,home?home:"",lib?lib:"");
  233.         ProcessMailcapFiles();
  234.         if( FirstMailcapEntry == NULL ){
  235.             fprintf(stderr,"ProcessMailcap: no mailcap found\n");
  236.             exit(1);
  237.         }
  238.     }
  239. }
  240.  
  241.  
  242. MMS_mailtoAvailableCtype(actype)
  243.     char *actype;
  244. {    struct MailcapEntry *mc;
  245.     char *ctype;
  246.  
  247.     MMS_ProcessMailcap(0);
  248.     for(mc = FirstMailcapEntry; mc; mc = mc->next ){
  249.         ctype = mc->contenttype;
  250.         if(ctype && index(ctype,'/') && !index(ctype,'*'))
  251.             if( strcmp(ctype,actype) == 0 )
  252.                 return 1;
  253.     }
  254.     return 0;
  255. }
  256. MMS_mailtoPrintTypes(out)
  257.     FILE *out;
  258. {    struct MailcapEntry *mc;
  259.     char *ctype;
  260.  
  261.     MMS_ProcessMailcap(0);
  262.     for(mc = FirstMailcapEntry; mc; mc = mc->next ){
  263.         ctype = mc->contenttype;
  264.         if(ctype && index(ctype,'/') && !index(ctype,'*'))
  265.             fprintf(out,"%s\n",mc->contenttype);
  266.     }
  267. }
  268.  
  269. char *
  270. MMS_mailtoGetCommand(ctype,entry)
  271.     char *ctype,*entry;
  272. {    char maintype[128],subtype[128],amaintype[128],asubtype[128];
  273.     char *actype;
  274.     struct MailcapEntry *mc;
  275.  
  276.     MMS_ProcessMailcap(0);
  277.  
  278.     strcpy(subtype,"*");
  279.     sscanf(ctype,"%[^/]/%s",maintype,subtype);
  280.  
  281.     for(mc = FirstMailcapEntry; mc; mc = mc->next ){
  282.         if( actype = mc->contenttype ){
  283.             if( strcmp(ctype,actype) == 0 )
  284.                 goto found;
  285.  
  286.             sscanf(actype,"%[^/]/%s",amaintype,asubtype);
  287.             if( strcmp(maintype,amaintype) == 0 ){
  288.                 if( strcmp(asubtype,"*") == 0 )
  289.                     goto found;
  290.             }
  291.         }
  292.     }
  293.     return 0;
  294.  
  295. found:
  296.     if( entry == 0 || *entry == 0 )        return mc->command;
  297.     if( strcmp(entry,"label") == 0 )    return mc->label;
  298.     if( strcmp(entry,"test") == 0 )        return mc->testcommand;
  299.     if( strcmp(entry,"edit") == 0 )        return mc->editcommand;
  300.     if( strcmp(entry,"compose") == 0 )    return mc->composecommand;
  301.     return 0;
  302. }
  303.  
  304. MMS_mailtoFinalize(){
  305.     return finalize();
  306. }
  307.  
  308. char *
  309. MMS_freshcopy(str){
  310.     extern char *freshcopy();
  311.     return freshcopy(str);
  312. }
  313.  
  314.  
  315. static write_to_file(fp)
  316.     FILE *fp;
  317. {    int size;
  318.  
  319.     fflush(fpout);
  320.     if( NGList ) fprintf(fp,"Newsgroups: %s\n",NGList);
  321.  
  322.     WriteOutMessage(fp, ToList, Subject, CCList, FirstPart);
  323.     TempCloseStyles(fp);
  324.  
  325.     fflush(fp);
  326.     size = ftell(fp);
  327.  
  328.     if( fp != stdout )
  329.         MMS_fseek(fp,0,0);
  330.     
  331.     return size;
  332. }
  333. FILE *
  334. MMS_synthWriteFile(file,sizep,encode_head)
  335.     char *file;
  336.     int *sizep;
  337. {    FILE *tfp,*fp;
  338.     int size = -1;
  339.  
  340.     if( file == 0 )
  341.         fp = stdout;
  342.     else{
  343.         if( *file == 0 )
  344.             sprintf(file,"%s",tmpname());
  345.  
  346.         fp = fopen(file,"w+");
  347.         if( fp == NULL )
  348.             goto EXIT;
  349.     }
  350.     if( encode_head ){
  351.         tfp = tmpfile();
  352.         write_to_file(tfp);
  353.         fflush(tfp);
  354.         fseek(tfp,0,0);
  355.         MIME_headerEncode(tfp,fp);
  356.         fclose(tfp);
  357.         fflush(fp);
  358.         size = ftell(fp);
  359.         fseek(fp,0,0);
  360.     }else    size = write_to_file(fp);
  361.  
  362. EXIT:
  363.     if( sizep )
  364.         *sizep = size;
  365.     return fp;
  366. }
  367.  
  368.  
  369. /*
  370.  *    suppress automatic header encoding in mailto
  371.  *    (This is called from calle of the WriteOutMessage)
  372.  */
  373. HeaderFputs(s, fp, hdr)
  374.     char *s;
  375.     FILE *fp;
  376.     char *hdr;
  377. {
  378.     fputs(s, fp);
  379. }
  380.